package com.dawn.module.hospital.service;

import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dawn.framework.common.pojo.CommonResult;
import com.dawn.framework.common.util.http.HttpUtils;
import com.dawn.framework.common.util.json.JsonUtils;
import com.dawn.framework.common.util.string.CodeUtils;
import com.dawn.framework.web.core.util.WebFrameworkUtils;
import com.dawn.module.hospital.controller.app.patient.vo.PatientCreateReqVO;
import com.dawn.module.hospital.controller.app.patient.vo.PatientDelReqVO;
import com.dawn.module.hospital.enums.BHConstants;
import com.dawn.module.hospital.controller.app.patient.vo.PatientQueryReqVO;
import com.dawn.module.hospital.service.ehealth.HealthCardService;
import com.dawn.module.hospital.service.ehealth.bean.*;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @description:
 * @author: cnsu-cmh
 * @time: 2024/8/7 12:06
 */
@Service
@Slf4j
public class PatientService extends BHService {

    @Resource
    @Lazy
    private HealthCardService healthCardService;

    public CommonResult getEHealthCfg() {
        EhealthCfg ehealthCfg = getEhealthCfg();
        return CommonResult.success(ehealthCfg);
    }

    public CommonResult list(PatientQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("openid",reqVO.getUserId());

        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_LIST.getValue(),params);
        if(httpResult.isError()) {
            return httpResult;
        }
        JSONArray jsonArray = (JSONArray)httpResult.getData();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String cardNo = jsonObject.getString("cardNo");
            if (BHConstants.ALIPAY_MINI_APPLET.getCode().equals(reqVO.getAppType())) {
                cardNo = CodeUtils.idCardMask(cardNo,1,17);
            } else {
                cardNo = CodeUtils.idCardMask(cardNo,3,14);
            }

            jsonObject.put("cardNo_",cardNo);

            String phone = jsonObject.getString("phone");
            phone = CodeUtils.phoneMask(phone,3,9);
            jsonObject.put("phone_",phone);

            String name = jsonObject.getString("name");
            name = CodeUtils.nameMask(name);
            jsonObject.put("name_",name);
        }

        if(jsonArray.size()>0){
            return CommonResult.success(jsonArray);
        }else {
            return CommonResult.error(ERROR_CODE,"未查询到病人档案信息!");
        }
    }

    public CommonResult exitWxPatient(String userId,String idCardNo) {
        Map params = new HashMap();
        params.put("openid",userId);
        params.put("cardNo",idCardNo);
        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_LIST.getValue(),params);
        if(httpResult.isError()) {
            return httpResult;
        }
        JSONArray jsonArray = (JSONArray)httpResult.getData();
        if(jsonArray.size()>0){
            return CommonResult.error(ERROR_CODE,"该身份证号已创建过档案!");
        }else {
            return CommonResult.success("");
        }
    }

    public CommonResult create(PatientCreateReqVO reqVO) {
        CommonResult isExitResult = exitWxPatient(reqVO.getOpenid(),reqVO.getCardNo());
        if(isExitResult.isError()){
            return isExitResult;
        }
        Map createParams = new HashMap<>();
        CommonResult findPatientResult = findPatientByCardNo(reqVO.getCardNo(), null);
        boolean create = true;
        if(findPatientResult.isSuccess()){
            JSONArray jsonArray = (JSONArray)findPatientResult.getData();
            List<Map> arrayList = JSONObject.parseArray(jsonArray.toJSONString(), Map.class);
            arrayList.sort(Comparator.comparing(m->String.valueOf(m.get("lastVisitDate"))));

            for (Map map : arrayList) {
                if(map.containsKey("patientId")) {
                    //存在档案
                    String patientId = String.valueOf(map.get("patientId"));
                    if(map.get("patientName")!=null) {
                        String patientName = String.valueOf(map.get("patientName"));
                        if(!patientName.equals(reqVO.getName())){
                            return CommonResult.error(ERROR_CODE,"患者姓名与医院系统档案姓名不一致，请确认信息是否正确");
                        }
                    }
                    createParams.put("patientId",patientId);
                    create = false;
                }
            }
        }

        String createRequestId = RandomUtil.randomNumbers(9);

        createParams.put("hisProvider",BHConstants.HIS_PROVIDER);
        createParams.put("tradeSerialNumber",createRequestId);
        createParams.put("cardNo",reqVO.getCardNo());
        createParams.put("cardTypeId",BHConstants.ID_CARD_TEXT);
        createParams.put("iDCardNo",reqVO.getCardNo());
        createParams.put("name",reqVO.getName());
        createParams.put("address",reqVO.getAddress());
        createParams.put("phone",reqVO.getPhone());
        createParams.put("amount","0.00");
//        createParams.put("settleCardType",isAli ? CS.PAY_CARD_ALI_HIS : CS.PAY_CARD_WX_HIS);
//        createParams.put("settleType",isAli ? CS.PAY_CARD_ALI_HIS : CS.PAY_CARD_WX_HIS);

        createParams.put("nation",reqVO.getNation());
        createParams.put("professionName",reqVO.getProfessionName());

        int gender = IdcardUtil.getGenderByIdCard(reqVO.getCardNo());
        String birth = IdcardUtil.getBirth(reqVO.getCardNo());
        int patientAge = IdcardUtil.getAgeByIdCard(reqVO.getCardNo());

        createParams.put("patSex",gender);//0-未知 1-男 2-女 9-未说明
        createParams.put("birthday",reqVO.getBirthday());
        createParams.put("firstCreate","0");
        createParams.put("isSelf",0);
        createParams.put("orderNo",createRequestId);
        createParams.put("tradeNo",createRequestId);

        if(create) {
            CommonResult createResult = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_CREATE_PATIENT_INFO.getValue(),createParams);
            if(createResult.isError()) {
                return createResult;
            }

            JSONObject createData = (JSONObject)createResult.getData();
            if(!org.springframework.util.StringUtils.hasLength(createData.getString("patientId"))) {
                return CommonResult.error(ERROR_CODE,"注册就诊卡到医院HIS系统失败.<br>HIS信息:"+createData.getString("resMsg"));
            } else {
                createParams.put("patientId",createData.getString("patientId"));
                createParams.put("patientNo",createData.getString("cardNo2"));
                createParams.put("clinicNo",createData.getString("clinicNo"));
                createParams.put("inPatientNO",createData.getString("inPatientNO"));
            }
        }

        createParams.put("ehealthCardId",reqVO.getEhealthCardId());
        createParams.put("birthday",birth);
        createParams.put("patientSexID",gender);
        createParams.put("patientAge",patientAge);
        createParams.put("patientSex",reqVO.getPatientSex());
        createParams.put("userId",reqVO.getOpenid());
        createParams.put("openid",reqVO.getOpenid());
        createParams.put("wxUserId",reqVO.getUserId());
        createParams.put("valid","1");
        CommonResult createResult = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_SAVE_PATIENT_INFO.getValue(),createParams);
//        JSONObject createData = (JSONObject)apiResult.getData();
//        createData.put("firstCreate",create);
        createParams.put("firstCreate",create);

        return CommonResult.success(createParams);
    }

    public CommonResult findPatientByCardNo(String idCardNo, String medicalCardNo) {
        Map findParams = new HashMap<>();
        findParams.put("hisProvider", BHConstants.HIS_PROVIDER);
        findParams.put("tradeSerialNumber", RandomUtil.randomNumbers(9));
        if(org.springframework.util.StringUtils.hasLength(medicalCardNo)) {
            findParams.put("cardNo",medicalCardNo);//卡号
            findParams.put("cardTypeId", BHConstants.MEDICAL_CARD_TEXT);
        } else {
            findParams.put("cardNo",idCardNo);//身份证
            findParams.put("cardTypeId", BHConstants.ID_CARD_TEXT);
        }

        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_INFO.getValue(),findParams);
        return httpResult;
    }

    public CommonResult delete(PatientDelReqVO reqVO) {
        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_DEL_PATIENT_INFO.getValue(),ImmutableMap.of("id", reqVO.getId()));
        return httpResult;
    }

    public CommonResult findPatientById(PatientDelReqVO reqVO) {
        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_ONE.getValue(),ImmutableMap.of("id", reqVO.getId()));
        return httpResult;
    }

    public CommonResult eHealthList(PatientQueryReqVO reqVO) {

        List<JSONObject> cardList = new ArrayList<>();

        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("openid",reqVO.getUserId());
        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_LIST.getValue(),params);
        if(httpResult.isSuccess()) {
            JSONArray jsonArray = (JSONArray)httpResult.getData();
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String ehealthCardId = jsonObject.getString("ehealthCardId");

                if (StringUtils.isNotBlank(ehealthCardId)) {
//                    cardList.add(jsonObject);
                    String idCard = jsonObject.getString("cardNo");

                    QRCodeReq codeReq = new QRCodeReq();
                    if (getEhealthCfg() != null) {
                        codeReq.setAppId(getEhealthCfg().getAppId());
                        codeReq.setAppSecret(getEhealthCfg().getAppSecret());
                        codeReq.setHospitalId(getEhealthCfg().getHospitalId());
                    }
                    codeReq.setHealthCardId(ehealthCardId);
                    codeReq.setIdNumber(idCard);
                    CommonResult qrCodeResult = healthCardService.getQRCode(codeReq);
                    if(qrCodeResult.isSuccess()) {
                        JSONObject codeResultData = (JSONObject)qrCodeResult.getData();
                        if(codeResultData.containsKey("qrCodeImg")) {
                            String ehealthCodeImage = String.valueOf(codeResultData.get("qrCodeImg"));
                            JSONObject card = new JSONObject();
                            card.put("id",jsonObject.get("id"));
                            card.put("name",jsonObject.get("name"));
                            card.put("cardNo_", idCard.substring(0,4) + "**********" + idCard.substring(idCard.length()-4));
                            card.put("ehealthCardIdStr", idCard.substring(0,4) + "**********" + idCard.substring(idCard.length()-4));
                            card.put("ehealthCodeImage", "data:image/jpg;base64," + ehealthCodeImage);
                            cardList.add(card);
                        }
                    }
                }
            }
        }

        return CommonResult.success(cardList);
    }

    public CommonResult getEHealthByCode(HealthCodeReq reqVO){
        if (getEhealthCfg() != null) {
            reqVO.setAppId(getEhealthCfg().getAppId());
            reqVO.setAppSecret(getEhealthCfg().getAppSecret());
            reqVO.setHospitalId(getEhealthCfg().getHospitalId());
        }
        CommonResult result = healthCardService.getHealthCardByHealthCode(reqVO);
        return result;
    }

    public CommonResult findPatientById(Long id) {
        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_ONE.getValue(), ImmutableMap.of("id",id));
        return httpResult;
    }

    public CommonResult updateClinicNo(Long wxUserId,Long id,String openid,String patientId,String cardNo) {
        CommonResult patientResult = findPatientById(id);
        JSONObject patient = (JSONObject)patientResult.getData();

        String clinicNo = "";
        /* 获取门诊号 */
        Map params = new HashMap<>();
        params.put("hisProvider",BHConstants.HIS_PROVIDER);
        params.put("patientId",patientId);
        params.put("cardNo",cardNo);
        params.put("cardTypeId",BHConstants.ID_CARD_TEXT);
        CommonResult pResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_VISIT_NO.getValue(), params);
        if(pResult.isSuccess()) {
            JSONObject resultMap = (JSONObject)pResult.getData();
//            List<HashMap> mapList = (List<HashMap>) resultMap.get("INFO");
            JSONArray jsonArray = resultMap.getJSONArray("INFO");
            List<Map> arrayList = JSONObject.parseArray(jsonArray.toJSONString(), Map.class);

            for (Map hashMap : arrayList) {
                clinicNo = String.valueOf(hashMap.get("MZH"));
            }
        }
        if(StringUtils.isNotBlank(clinicNo)){
//            Map args = new HashMap<>();
//            args.put("id",id);
//            args.put("wxUserId",wxUserId);
//            args.put("openid",openid);
//            args.put("clinicNo",clinicNo);
//            args.put("phone",patient.getString("phone"));
//            args.put("cardNo",patient.getString("cardNo"));
            patient.put("clinicNo",clinicNo);
            patient.remove("lastUpdateTime");
            patient.remove("createTime");
            patient.remove("memo");
            CommonResult httpResult = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_SAVE_PATIENT_INFO.getValue(), patient);
            log.info("********** 更新门诊号 **********httpResult："+ JsonUtils.toJsonString(httpResult));
        }

        patientResult = findPatientById(id);
        return patientResult;
    }

    public CommonResult registerUniformVerifyOrder(RegisterUniformVerifyOrderReq reqVO) {
        if (getEhealthCfg() != null) {
            reqVO.setAppId(getEhealthCfg().getAppId());
            reqVO.setAppSecret(getEhealthCfg().getAppSecret());
            reqVO.setHospitalId(getEhealthCfg().getHospitalId());
        }
        CommonResult result = healthCardService.registerUniformVerifyOrder(reqVO);
        return result;
    }

    public CommonResult checkUniformVerifyResult(CheckUniformVerifyReq reqVO) {
        if (getEhealthCfg() != null) {
            reqVO.setAppId(getEhealthCfg().getAppId());
            reqVO.setAppSecret(getEhealthCfg().getAppSecret());
            reqVO.setHospitalId(getEhealthCfg().getHospitalId());
        }
        CommonResult result = healthCardService.checkUniformVerifyResult(reqVO);
        if (result.isSuccess()) {
            JSONObject resultData = (JSONObject)result.getData();
            Boolean suc = resultData.getBoolean("suc");
            if (suc) {
                HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_VERIFY_PATIENT_INFO.getValue(),ImmutableMap.of("id", reqVO.getId()));
            }
        }
        return result;
    }

    public CommonResult findPatientEHealthById(PatientDelReqVO reqVO) {
        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_ONE.getValue(),ImmutableMap.of("id", reqVO.getId()));
        if (httpResult.isError()) {
            return httpResult;
        }
        JSONObject jsonObject = (JSONObject)httpResult.getData();
        String ehealthCardId = jsonObject.getString("ehealthCardId");
        String idCard = jsonObject.getString("cardNo");;

        if (StringUtils.isEmpty(ehealthCardId)) {
            return CommonResult.error(ERROR_CODE,"电子健康卡ID为空，请先绑定电子健康卡");
        }
        JSONObject card = new JSONObject();
        card.put("ehealthCardIdStr", idCard.substring(0,4) + "**********" + idCard.substring(idCard.length()-4));

        QRCodeReq codeReq = new QRCodeReq();
        if (getEhealthCfg() != null) {
            codeReq.setAppId(getEhealthCfg().getAppId());
            codeReq.setAppSecret(getEhealthCfg().getAppSecret());
            codeReq.setHospitalId(getEhealthCfg().getHospitalId());
        }
        codeReq.setHealthCardId(ehealthCardId);
        codeReq.setIdNumber(idCard);
        CommonResult codeResult = healthCardService.getQRCode(codeReq);

        if(codeResult.isSuccess()) {
            JSONObject codeResultData = (JSONObject)codeResult.getData();
            if(codeResultData.containsKey("qrCodeImg")) {
                String ehealthCodeImage = codeResultData.getString("qrCodeImg");
                card.put("ehealthCodeImage", "data:image/jpg;base64," + ehealthCodeImage);
            } else {
                return CommonResult.error(ERROR_CODE,"电子健康卡二维码为空，请先绑定电子健康卡");
            }

            // 绑定健康卡和院内ID关系
            if(codeResultData.containsKey("qrCodeText")) {
                String qrCodeText = codeResultData.getString("qrCodeText");
                BindCardReq bindCardReq = new BindCardReq();
                if (getEhealthCfg() != null) {
                    bindCardReq.setAppId(getEhealthCfg().getAppId());
                    bindCardReq.setAppSecret(getEhealthCfg().getAppSecret());
                    bindCardReq.setHospitalId(getEhealthCfg().getHospitalId());
                }
                bindCardReq.setQrCodeText(qrCodeText);
                healthCardService.bindCardRelation(bindCardReq);
            }
        }

        String phone = jsonObject.getString("phone");
        phone = CodeUtils.phoneMask(phone,3,9);

        card.put("name", jsonObject.getString("name"));
        card.put("phone", phone);
        card.put("id", jsonObject.getLong("id"));

        return CommonResult.success(card);
    }

    public CommonResult takeMsCard(PatientDelReqVO reqVO) {
        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_ONE.getValue(),ImmutableMap.of("id", reqVO.getId()));
        if (httpResult.isError()) {
            return httpResult;
        }
        JSONObject jsonObject = (JSONObject)httpResult.getData();
        String ehealthCardId = jsonObject.getString("ehealthCardId");
        String idCard = jsonObject.getString("cardNo");;

        if (!StringUtils.isEmpty(ehealthCardId)) {
            QRCodeReq codeReq = new QRCodeReq();
            if (getEhealthCfg() != null) {
                codeReq.setAppId(getEhealthCfg().getAppId());
                codeReq.setAppSecret(getEhealthCfg().getAppSecret());
                codeReq.setHospitalId(getEhealthCfg().getHospitalId());
            }
            codeReq.setHealthCardId(ehealthCardId);
            codeReq.setIdNumber(idCard);
            CommonResult codeResult = healthCardService.getQRCode(codeReq);
            if(codeResult.isSuccess()) {
                JSONObject codeResultData = (JSONObject)codeResult.getData();
                if(codeResultData.containsKey("qrCodeText")) {
                    String qrCodeText = codeResultData.getString("qrCodeText");
                    HealthCodeReq healthCodeReq = new HealthCodeReq();
                    if (getEhealthCfg() != null) {
                        healthCodeReq.setAppId(getEhealthCfg().getAppId());
                        healthCodeReq.setAppSecret(getEhealthCfg().getAppSecret());
                        healthCodeReq.setHospitalId(getEhealthCfg().getHospitalId());
                    }
                    healthCodeReq.setQrCodeText(qrCodeText);
                    return healthCardService.getOrderIdByOutAppId(healthCodeReq);
                }
            } else {
                return codeResult;
            }
        }
        return CommonResult.error(ERROR_CODE,"电子健康卡数据异常");
    }

    public CommonResult findPatientByOpenId(String openId) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("openid",openId);

        CommonResult httpResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_PATIENT_LIST.getValue(),params);
        return httpResult;
    }

    public String getClinicNoByPatientId(String patientId) {
        String clinicNo = null;
        /* 获取门诊号 */
        Map params = new HashMap<>();
        params.put("hisProvider",BHConstants.HIS_PROVIDER);
        params.put("patientId",patientId);
        params.put("cardNo","0");
        params.put("cardTypeId",BHConstants.ID_CARD_TEXT);
        CommonResult pResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_VISIT_NO.getValue(), params);
        if(pResult.isSuccess()) {
            JSONObject resultMap = (JSONObject)pResult.getData();
            JSONArray jsonArray = resultMap.getJSONArray("INFO");
            List<Map> arrayList = JSONObject.parseArray(jsonArray.toJSONString(), Map.class);

            for (Map hashMap : arrayList) {
                clinicNo = String.valueOf(hashMap.get("MZH"));
            }
        }

        return clinicNo;
    }
}
